<template lang="pug">
    .ace-editor-wrapper(:style='{ height: height, width: width }', ref='ace-editor')
</template>

<script>
import * as ace from 'brace'
import 'brace/mode/javascript'
import 'brace/theme/monokai'
import 'brace/ext/beautify'
import 'brace/ext/searchbox'

export default {
    props: {
        content: {
            // 初始值
            type: String,
            default: '',
        },
        mode: {
            // 语言
            type: String,
            default: 'javascript',
        },
        theme: {
            // 主题
            type: String,
            default: 'chrome',
        },
        height: {
            type: String,
            default: '300px',
        },
        width: {
            type: String,
            default: '100%',
        },
        showGutter: {
            // 是否展示左侧line-number
            type: Boolean,
            default: true,
        },
        showPrintMargin: {
            // 是否在编辑器的第xx列位置显示分割线
            type: Boolean,
            default: false,
        },
        fontSize: {
            // 字体大小
            type: String,
            default: '12px',
        },
        sync: {
            type: Boolean,
            default: false,
        },
        options: {
            type: Object,
            default: () => ({}),
        },
        readOnly: {
            type: Boolean,
            default: false,
        },
        insert: {
            type: String,
        },
    },
    components: {},
    data() {
        return {
            editor: undefined,
            value: this.content,
        }
    },
    mounted() {
        this.init()
    },
    methods: {
        init() {
            const {mode, theme, showGutter, showPrintMargin, fontSize, content, options, readOnly} = this
            // eslint-disable-next-line unicorn/consistent-destructuring
            const editor = ace.edit(this.$refs['ace-editor'], {
                IncrementalSearch: false,
            })
            editor.setOption('wrap', true)
            editor.$blockScrolling = Number.POSITIVE_INFINITY
            // eslint-disable-next-line import/no-dynamic-require
            require(`brace/mode/${mode}`)
            editor.getSession().setMode(`ace/mode/${mode}`)
            // eslint-disable-next-line import/no-dynamic-require
            require(`brace/theme/${theme}`)
            editor.setTheme(`ace/theme/${theme}`)
            editor.renderer.setShowGutter(showGutter)
            editor.setShowPrintMargin(showPrintMargin)
            editor.setFontSize(fontSize)
            editor.setValue(content, 1)
            editor.setOptions(options)
            // eslint-disable-next-line unicorn/consistent-destructuring
            editor.on('change', this.handleOnChange)
            editor.setReadOnly(readOnly)
            this.editor = editor
        },
        setValue(newContent) {
            // eslint-disable-next-line unicorn/no-this-assignment
            const vm = this
            if (vm.sync) {
                vm.editor.setValue(newContent, 1)
            }
        },
        handleOnChange() {
            this.$emit('on-change', this.editor.getValue())
        },
        handleGetValue() {
            return this.editor.getValue()
        },
    },
    computed: {},
    filters: {},
    watch: {
        insert(newContent) {
            // eslint-disable-next-line unicorn/no-this-assignment
            const vm = this
            if (vm.sync) {
                vm.editor.insert(newContent, 1)
            }
        },
        // eslint-disable-next-line sonarjs/no-identical-functions
        content(newContent) {
            // eslint-disable-next-line unicorn/no-this-assignment
            const vm = this
            if (vm.sync) {
                vm.editor.setValue(newContent, 1)
            }
        },
        theme(newTheme) {
            // eslint-disable-next-line unicorn/no-this-assignment
            const vm = this
            vm.editor.setTheme(`ace/theme/${newTheme}`)
        },
        height() {
            // eslint-disable-next-line unicorn/no-this-assignment
            const vm = this
            vm.editor.resize()
        },
        readOnly(value) {
            // eslint-disable-next-line unicorn/no-this-assignment
            const vm = this
            vm.editor.setReadOnly(value)
        }
    },
}
</script>

<style lang="sass" scoped>
</style>
